package com.homedo.microservice.open.service.gateway.service;

import com.google.common.collect.Lists;
import com.homedo.common.bean.vo.context.UserContext;
import com.homedo.common.dao.bean.po.base.BasePo;
import com.homedo.common.dao.bean.po.enhanced.base.BaseEnhanced;
import com.homedo.common.service.BaseService;
import com.homedo.common.util.Detect;
import com.homedo.microservice.open.service.gateway.bean.enums.forroute.StatusEnum4Route;
import com.homedo.microservice.open.service.gateway.bean.po.Route;
import com.homedo.microservice.open.service.gateway.bean.po.enhanced.RouteDomainEnhanced;
import com.homedo.microservice.open.service.gateway.bean.po.enhanced.RouteEnhanced;
import com.homedo.microservice.open.service.gateway.bean.po.enhanced.RouteServiceEnhanced;
import com.homedo.microservice.open.service.gateway.bean.po.enhanced.RouteVersionEnhanced;
import com.homedo.microservice.open.service.gateway.persistence.dao.RouteDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 作者 jgshun
 * @date 创建时间 2018年09月18日 11时30分20秒
 */
@Service
public class RouteService extends BaseService<Route> {
    @Autowired
    private RouteDao routeDao;
    @Autowired
    private RouteDomainService routeDomainService;
    @Autowired
    private RouteServiceService routeServiceService;
    @Autowired
    private RouteVersionService routeVersionService;


    @Override
    public List<RouteEnhanced> getEnhanceds(List<?> ids, UserContext userContext) {
        List<Route> routes = routeDao.getListByIds(ids, Route.class);

        if (!Detect.notEmpty(routes)) {
            return null;
        }

        List<RouteEnhanced> routeEnhanceds = this.convent2Enhanceds(routes);

        this.appendEnhancedCommons(routeEnhanceds, userContext);

        return routeEnhanceds;
    }


    @Override
    public List<RouteEnhanced> getEnhanceds4Active(List<?> ids, UserContext userContext) {
        List<Route> routes = routeDao.getListByIdsGreaterThanMark0(ids, Route.class);

        if (!Detect.notEmpty(routes)) {
            return null;
        }
        List<RouteEnhanced> routeEnhanceds = this.convent2Enhanceds(routes);

        this.appendEnhancedCommons(routeEnhanceds, userContext);

        return routeEnhanceds;
    }


    @Override
    public List<RouteEnhanced> convent2Enhanceds(List<? extends BasePo> pos) {
        List<Route> routes = (List<Route>) pos;
        List<RouteEnhanced> routeEnhanceds = Lists.newArrayList();
        routes.forEach(e -> routeEnhanceds.add(new RouteEnhanced(e)));
        return routeEnhanceds;
    }


    public List<RouteEnhanced> getEnhanceds4Application(String applicationName, List<StatusEnum4Route> statuses, UserContext userContext) {
        List<Route> routes = routeDao.getByApplication(applicationName, statuses);

        if (!Detect.notEmpty(routes)) {
            return null;
        }
        List<RouteEnhanced> routeEnhanceds = this.convent2Enhanceds(routes);

        this.appendEnhancedCommons(routeEnhanceds, userContext);

        return routeEnhanceds;
    }

    @Override
    public List<RouteEnhanced> appendEnhancedCommons(List<? extends BaseEnhanced> enhancedItems, UserContext userContext) {
        List<RouteEnhanced> routeEnhanceds = (List<RouteEnhanced>) enhancedItems;

        this.appendRouteServiceEnhanced(routeEnhanceds, userContext);
        this.appendRouteDomainEnhanced(routeEnhanceds, userContext);
        this.appendRouteVersionEnhanceds(routeEnhanceds, userContext);

        return routeEnhanceds;
    }

    public List<RouteEnhanced> appendRouteVersionEnhanceds(List<RouteEnhanced> routeEnhanceds, UserContext userContext) {

        List<String> routeIds = routeEnhanceds.stream().map(RouteEnhanced::getId).collect(Collectors.toList());

        List<RouteVersionEnhanced> routeVersionEnhanceds = routeVersionService.getEnhanceds4Route(routeIds, userContext);

        if (!Detect.notEmpty(routeVersionEnhanceds)) {
            return routeEnhanceds;
        }

        this.appendRouteVersionEnhanceds(routeEnhanceds, routeVersionEnhanceds, userContext);

        return routeEnhanceds;

    }

    public List<RouteEnhanced> appendRouteDomainEnhanced(List<RouteEnhanced> routeEnhanceds, UserContext userContext) {
        List<Integer> routeDomainIds = routeEnhanceds.stream()
                .map(RouteEnhanced::getRouteDomainEnhanced).filter(e -> e != null && e.getId() != null && e.getId() > 0).collect(Collectors.toList())
                .stream().map(RouteDomainEnhanced::getId).collect(Collectors.toList());
        if (!Detect.notEmpty(routeDomainIds)) {
            return routeEnhanceds;
        }
        List<RouteDomainEnhanced> routeDomainEnhanceds = routeDomainService.getEnhanceds(routeDomainIds, userContext);

        if (!Detect.notEmpty(routeDomainEnhanceds)) {
            return routeEnhanceds;
        }

        this.appendRouteDomainEnhanced(routeEnhanceds, routeDomainEnhanceds, userContext);

        return routeEnhanceds;
    }

    public List<RouteEnhanced> appendRouteServiceEnhanced(List<RouteEnhanced> routeEnhanceds, UserContext userContext) {
        List<String> routeServiceIds = routeEnhanceds.stream()
                .map(RouteEnhanced::getRouteServiceEnhanced).filter(e -> e != null && Detect.notEmpty(e.getId())).collect(Collectors.toList())
                .stream().map(RouteServiceEnhanced::getId).collect(Collectors.toList());
        if (!Detect.notEmpty(routeServiceIds)) {
            return routeEnhanceds;
        }


        List<RouteServiceEnhanced> routeServiceEnhanceds = routeServiceService.getEnhanceds(routeServiceIds, userContext);

        if (!Detect.notEmpty(routeServiceEnhanceds)) {
            return routeEnhanceds;
        }

        this.appendRouteServiceEnhanced(routeEnhanceds, routeServiceEnhanceds, userContext);

        return routeEnhanceds;
    }

    private void appendRouteServiceEnhanced(List<RouteEnhanced> routeEnhanceds, List<RouteServiceEnhanced> routeServiceEnhanceds, UserContext userContext) {
        routeEnhanceds.forEach(e -> {
            this.appendRouteServiceEnhanced(e, routeServiceEnhanceds, userContext);
        });
    }

    private void appendRouteServiceEnhanced(RouteEnhanced routeEnhanced, List<RouteServiceEnhanced> routeServiceEnhanceds, UserContext userContext) {
        routeServiceEnhanceds.forEach(e -> {
            if (routeEnhanced.getRouteServiceEnhanced() != null && e.getId().equals(routeEnhanced.getRouteServiceEnhanced().getId())) {
                routeEnhanced.setRouteServiceEnhanced(e);
                return;
            }
        });
    }


    private void appendRouteDomainEnhanced(List<RouteEnhanced> routeEnhanceds, List<RouteDomainEnhanced> routeDomainEnhanceds, UserContext userContext) {
        routeEnhanceds.forEach(e -> {
            this.appendRouteDomainEnhanced(e, routeDomainEnhanceds, userContext);
        });
    }

    private void appendRouteDomainEnhanced(RouteEnhanced routeEnhanced, List<RouteDomainEnhanced> routeDomainEnhanceds, UserContext userContext) {
        routeDomainEnhanceds.forEach(e -> {
            if (routeEnhanced.getRouteDomainEnhanced() != null && e.getId() == routeEnhanced.getRouteDomainEnhanced().getId().intValue()) {
                routeEnhanced.setRouteDomainEnhanced(e);
                return;
            }
        });
    }

    private void appendRouteVersionEnhanceds(List<RouteEnhanced> routeEnhanceds, List<RouteVersionEnhanced> routeVersionEnhanceds, UserContext userContext) {
        routeEnhanceds.forEach(e -> {
            this.appendRouteVersionEnhanceds(e, routeVersionEnhanceds, userContext);
        });
    }

    private void appendRouteVersionEnhanceds(RouteEnhanced routeEnhanced, List<RouteVersionEnhanced> routeVersionEnhanceds, UserContext userContext) {
        List<RouteVersionEnhanced> curRouteVersionEnhanced = Lists.newArrayList();
        routeVersionEnhanceds.forEach(e -> {
            if (e.getRouteEnhanced().getId().equals(routeEnhanced.getId())) {
                curRouteVersionEnhanced.add(e);
            }
        });
        routeEnhanced.setRouteVersionEnhanceds(curRouteVersionEnhanced);
    }
}
